package cn.topevery.garden.wapi.handler;

import cn.topevery.garden.dal.logic.*;
import cn.topevery.garden.dal.logic.warning.IotDeviceIrrigationWarning;
import cn.topevery.garden.dal.logic.warning.IotDeviceToiletsWarning;
import cn.topevery.garden.dal.logic.warning.IotDeviceWaterQualityWarning;
import cn.topevery.garden.entity.po.*;
import cn.topevery.garden.framework.base.IoTHandlerBase;
import cn.topevery.garden.wapi.utils.SpringUtil;
import com.github.dozermapper.core.Mapper;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ：peng.tian
 * @date ：Created in 2021/9/9 9:43
 * @description：中志环境IoT设备协议处理
 */
public class ZhongZhi_IoTHandler extends IoTHandlerBase {
    @Override
    public Boolean isProcess(byte[] input) throws UnsupportedEncodingException {
        return input.length > 10 && new String(input, 0, 2, "UTF-8").equals("##");
    }

    Mapper mapper;
    IotDeviceIrrigationLogic iotDeviceIrrigationLogic;
    IotDeviceIrrigationLogLogic iotDeviceIrrigationLogLogic;
    IotDeviceToiletsLogic iotDeviceToiletsLogic;
    IotDeviceToiletsLogLogic iotDeviceToiletsLogLogic;
    IotDeviceWaterQualityLogic iotDeviceWaterQualityLogic;
    IotDeviceWaterQualityLogLogic iotDeviceWaterQualityLogLogic;
    IotDeviceWaterQualityWarning iotDeviceWaterQualityWarning;
    IotDeviceToiletsWarning iotDeviceToiletsWarning;
    IotDeviceIrrigationWarning iotDeviceIrrigationWarning;

    public ZhongZhi_IoTHandler() {
        iotDeviceWaterQualityLogic = (IotDeviceWaterQualityLogic) SpringUtil.getBean("iotDeviceWaterQualityLogic");
        iotDeviceWaterQualityLogLogic = (IotDeviceWaterQualityLogLogic) SpringUtil.getBean("iotDeviceWaterQualityLogLogic");
        iotDeviceIrrigationLogic = (IotDeviceIrrigationLogic) SpringUtil.getBean("iotDeviceIrrigationLogic");
        iotDeviceIrrigationLogLogic = (IotDeviceIrrigationLogLogic) SpringUtil.getBean("iotDeviceIrrigationLogLogic");
        iotDeviceToiletsLogic = (IotDeviceToiletsLogic) SpringUtil.getBean("iotDeviceToiletsLogic");
        iotDeviceToiletsLogLogic = (IotDeviceToiletsLogLogic) SpringUtil.getBean("iotDeviceToiletsLogLogic");
        iotDeviceWaterQualityWarning = (IotDeviceWaterQualityWarning) SpringUtil.getBean("iotDeviceWaterQualityWarning");
        iotDeviceToiletsWarning = (IotDeviceToiletsWarning) SpringUtil.getBean("iotDeviceToiletsWarning");
        iotDeviceIrrigationWarning = (IotDeviceIrrigationWarning) SpringUtil.getBean("iotDeviceIrrigationWarning");
        mapper = (Mapper) SpringUtil.getBean("dozerMapper");
    }


    @Override
    public String onProcess(byte[] input) throws UnsupportedEncodingException {

        String result = "2";

        Map data = decoder(input);
        if (data != null) {
            if (data.containsKey("st")) {
                Integer ST = Integer.parseInt(data.get("st").toString());
                if (ST.equals(23)) {
                    //保存设备数据
                    IotDeviceToilets entity = mapper.map(data, IotDeviceToilets.class);
                    IotDeviceToiletsLog logEntity = mapper.map(data, IotDeviceToiletsLog.class);
                    IotDeviceToilets oldEntity = iotDeviceToiletsLogic.getEntityByColumn("c_data_id", logEntity.deviceCode);
                    entity.dataId = entity.deviceCode;
                    if (oldEntity != null) {
                        entity.id = oldEntity.id;
                        entity.dbStatus = oldEntity.dbStatus;
                    }
                    iotDeviceToiletsLogic.saveOrUpdate("0", entity);
                    iotDeviceToiletsLogLogic.saveOrUpdate("0", logEntity);
                    //预警检测
                    iotDeviceToiletsWarning.check(logEntity);
                } else if (ST.equals(25)) {
                    //保存设备数据
                    IotDeviceIrrigation entity = mapper.map(data, IotDeviceIrrigation.class);
                    IotDeviceIrrigationLog logEntity = mapper.map(data, IotDeviceIrrigationLog.class);
                    IotDeviceIrrigation oldEntity = iotDeviceIrrigationLogic.getEntityByColumn("c_data_id", logEntity.deviceCode);
                    entity.dataId = entity.deviceCode;
                    if (oldEntity != null) {
                        entity.id = oldEntity.id;
                        entity.dbStatus = oldEntity.dbStatus;
                    }
                    iotDeviceIrrigationLogic.saveOrUpdate("0", entity);
                    iotDeviceIrrigationLogLogic.saveOrUpdate("0", logEntity);
                    //预警检测
                    iotDeviceIrrigationWarning.check(logEntity);
                } else if (ST.equals(53) || ST.equals(32)) {
                    //保存设备数据
                    IotDeviceWaterQuality entity = mapper.map(data, IotDeviceWaterQuality.class);
                    IotDeviceWaterQualityLog logEntity = mapper.map(data, IotDeviceWaterQualityLog.class);
                    IotDeviceWaterQuality oldEntity= iotDeviceWaterQualityLogic.getEntityByColumn("c_data_id", logEntity.deviceCode);

                    entity.dataId = entity.deviceCode;
                    if (oldEntity != null) {
                        entity.id = oldEntity.id;
                        entity.dbStatus = oldEntity.dbStatus;
                    }
                    try{
                        iotDeviceWaterQualityLogic.saveOrUpdate("0", entity);
                        iotDeviceWaterQualityLogLogic.saveOrUpdate("0", logEntity);
                    }catch (Exception ex){
                        System.out.println(ex);
                    }

                    //预警处理
                    iotDeviceWaterQualityWarning.check(logEntity);
                }  else if (ST.equals(54)) {
                    System.out.println("未实现数据接入!");
                } else {
                    System.out.println("未知设备" + data.get("st") + "!");
                }
            }
        }
        else{
            System.out.println("不支持的接入数据!");
        }
        //处理逻辑
        return result;
    }

    private Map decoder(byte[] input) throws UnsupportedEncodingException {
        Map result = new HashMap<>();
        String inputData = new String(input, 0, input.length, "UTF-8");
        Integer inputDataLen;
        Integer dataLen;
        try {
            dataLen = Integer.parseInt(new String(input, 2, 4, "UTF-8"));
            inputData = inputData.substring(6, inputData.length() - 4);
            inputDataLen = inputData.length();
        } catch (Exception ex) {
            //没有数据长度校验位
            dataLen = input.length;
            inputDataLen = input.length;
            inputData = inputData.substring(2, inputData.length() - 2);
        }

        List<String> CNlist = new ArrayList<>();
        CNlist.add("2011");

        String semicolon = ";";
        if (dataLen.equals(inputDataLen)) {
            String[] columns = inputData.replace("&&", semicolon).replace(",", semicolon).split(semicolon);
            for (int i = 0; i < columns.length; i++) {
                String[] splitData = columns[i].split("=");
                if (splitData.length == 2) {
                    //全部转小写以及处理不合法字符
                    String name = splitData[0].replace("-", "").toLowerCase();
                    Object value = splitData[1];
                    if (name.equals("datatime") || name.equals("qn")) {
                        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
                        LocalDateTime time = LocalDateTime.now();
                        value = value.toString().substring(0, 14);
                        value = LocalDateTime.parse(value.toString(), df);
                    }
                    if (name.equals("datatime")) {
                        name = "date";
                    }
                    if (name.equals("mn")) {
                        name = "deviceCode";
                    }
                    if (name.equals("cn") && StringUtils.isNotBlank(value.toString())) {
                        if (!CNlist.contains(value.toString())) {
                            return null;
                        }
                    }

                    result.put(name, value);
                }
            }
        }
        return result;
    }
}
